Un dominio è, nella pratica della semantica denotazionale, una CPO: un ordine parziale completo dotato di elemento minimo . Questo articolo dà per acquisita la teoria degli ordini, poset, catene e lub, CPO e CPO, funzioni monotone e continue, Teorema di Kleene, e si concentra su un'altra domanda: come si costruiscono i domini in modo compositivo, e perché le funzioni che vi operano risultano continue.
La motivazione è dare semantica denotazionale a un linguaggio funzionale tipato (l'esempio di riferimento è HOFL, Higher-Order Functional Language). Servono allora non un dominio, ma una famiglia intera: un dominio per ciascun tipo
in modo che ogni termine denoti un valore (dove è un ambiente type-sensitive che assegna alle variabili valori del dominio giusto). Inoltre, poiché HOFL ha la ricorsione , il significato si ottiene risolvendo un'equazione ricorsiva tramite , e quindi ogni deve essere una CPO e ogni funzionale coinvolto deve essere continuo.
La strategia è compositiva: si fissa il dominio base e si forniscono dei costruttori che, dati e , producono e . Il requisito cruciale è che ogni costruttore preservi la struttura di CPO, e che le operazioni associate (proiezioni, applicazione, ricorsione…) siano continue.
Il tipo base si interpreta nel dominio piatto : gli interi più un che rappresenta la non terminazione. Essendo un ordine piatto è automaticamente una CPO (ha bottom e ammette solo catene finite).
Le operazioni aritmetiche si sollevano al dominio piatto come estensioni strette : il risultato vale quando entrambi gli argomenti sono interi (), e vale altrimenti (cioè non appena oppure ).
"Stretta" significa che si propaga: se un argomento diverge, diverge il risultato. Queste funzioni sono monotone e continue, automaticamente, poiché il loro dominio ammette solo catene finite (vale il lemma "niente catene infinite monotona = continua").
Date due CPO ed , il prodotto cartesiano si ordina componente per componente:
Si verifica che è ancora una CPO:
- è un poset: riflessività, antisimmetria e transitività si ereditano da quelle di ed ;
- ha bottom , perché per ogni coppia;
- è completo: il lub di una catena si calcola componente per componente,
È un maggiorante (ogni componente lo è) ed è il minimo dei maggioranti (se maggiora la catena, allora maggiora ed maggiora , da cui la disuguaglianza componente per componente).
Le proiezioni e sono monotone e continue. La continuità di , ad esempio, è immediata dalla definizione di lub di coppie:
Variante: prodotto smashed. Talvolta si usa il prodotto "schiacciato" , che identifica in un unico bottom tutte le coppie con almeno una componente indefinita. È un buon esercizio verificare che anch'esso è una CPO.
Prima di affrontare lo spazio delle funzioni serve uno strumento tecnico, tanto semplice da enunciare quanto utile: lo switch lemma, che dice quando è lecito scambiare l'ordine di due lub annidati.
Lemma (switch). Sia una CPO e una famiglia doppiamente indicizzata, monotona in entrambi gli indici:
Allora ogni riga, ogni colonna e la diagonale sono catene, e i tre modi di "saturare" la matrice coincidono:
Idea della dimostrazione. Si prova che tutti questi insiemi hanno lo stesso insieme di maggioranti (per riga: ogni elemento di una riga sta sotto al lub di riga; per diagonale: ogni sta sotto a con , perché e ). Avendo gli stessi maggioranti, hanno lo stesso minimo dei maggioranti.
Intuitivamente: per calcolare il limite di una "matrice crescente" si può procedere per righe, per colonne o lungo la diagonale, ottenendo sempre lo stesso risultato.
Date due CPO ed , il dominio funzionale è l'insieme delle funzioni continue da a , non tutte le funzioni, solo quelle continue, ordinate punto a punto:
Conviene avere in mente alcuni esempi su . Due funzioni totali distinte sono sempre inconfrontabili (ogni funzione totale è massimale): per avere con occorre che sia indefinita () là dove è definita, e che coincidano altrove. L'ordine misura quindi quanto una funzione "raffina" l'altra estendendone il dominio di definizione.
Anche è una CPO:
- è un poset, con relazione ereditata punto a punto da ;
- ha bottom , la funzione ovunque indefinita;
- è completo, e questo richiede due passi.
1. Ogni catena di funzioni (anche non continue) ha come lub la funzione definita punto a punto
che è un maggiorante ed è il minimo dei maggioranti (entrambe le verifiche si fanno punto a punto).
2. Se le sono continue, allora anche lo è, ed è qui che interviene lo switch lemma. Data una catena in :
Lo scambio centrale dei due lub è lecito perché la famiglia è monotona in entrambi gli indici: se e allora (per continuità/monotonia di e per ).
Poiché il limite di una catena di funzioni continue è continuo, esso appartiene a , che risulta dunque chiuso e completo. Ricordiamo infine che la composizione di funzioni continue è continua, cioè se e allora .
Per completare la cassetta degli attrezzi servono altri due costruttori.
Il sollevamento (lifting) di una CPO è . Attenzione: non è l'ordine piatto. Il lifting aggiunge un nuovo bottom strettamente sotto a una copia fedele di , conservandone l'ordine interno:
È una CPO, con . L'operatore di lifting trasforma in con e : è ben definito, monotono e continuo. Su di esso si basa la comoda notazione di de-lifting , che estrae il valore da (se definito) e lo assegna a in , propagando altrimenti .
La somma disgiunta affianca i due domini tenendoli separati (tramite iniezioni continue ); serve a interpretare i tipi unione. La costruzione dell'ordine, del bottom e delle iniezioni è un utile esercizio.
Verificare la continuità "a mano" di ogni funzione semantica sarebbe poco pratico. I teoremi di continuità permettono di ridurre il problema a controlli più semplici, e forniscono un compendio di operatori già noti essere continui.
Teorema. Sia e poniamo . Allora è continua se e solo se e lo sono.
La direzione segue dal fatto che le proiezioni sono continue e la composizione di funzioni continue è continua. La direzione si calcola componente per componente, usando che e che il lub nelle coppie è componente per componente. In pratica: una funzione a valori in un prodotto è continua esattamente quando lo sono le sue componenti.
Teorema. Sia . Definite le applicazioni parziali
allora è continua se e solo se è continua per ogni e è continua per ogni .
Questo è uno dei risultati più usati: per stabilire la continuità di una funzione a due argomenti basta controllarla un argomento alla volta. La direzione delicata è : data una catena in , si separa il lub di coppie e si applica la continuità prima su un argomento e poi sull'altro, usando infine lo switch lemma per ricomporre il doppio lub
applicabile perché è monotona in e in (le applicazioni parziali sono monotone).
Attenzione. Continuità (e perfino monotonia) separata va verificata con cura: una funzione può essere ben definita "come grafo" ma non monotona se "guarda" se un argomento è . Ad esempio se e non è nemmeno monotona, perché valori prodotti quando gli argomenti si raffinano.
I teoremi precedenti permettono di dimostrare che i costituenti della semantica denotazionale sono continui:
- Applicazione , con , è continua (la si verifica separatamente nei due argomenti: fissato è continua perché lo è; fissato è continua per la definizione di lub punto a punto nel dominio funzionale). Dunque .
- Punto fisso , con , è esso stesso continuo. La dimostrazione mostra per induzione su che ogni è continua (caso base: funzione costante ; passo induttivo: usa lo switch lemma), e poi conclude che è continua perché lub di funzioni continue. Questo è esattamente ciò che rende ben definita e compositiva la denotazione di .
- Currying e il suo inverso preservano la continuità e sono mutuamente inversi: stabiliscono l'isomorfismo , la versione "su domini" della corrispondenza tra funzioni a due argomenti e funzioni che restituiscono funzioni.
In definitiva, i costruttori (prodotto, spazio funzionale, lifting, somma) sono chiusi rispetto alla struttura di CPO, e gli operatori fondamentali sono continui: abbiamo così un linguaggio completo per costruire, in modo compositivo, i domini e le funzioni semantiche di un linguaggio funzionale di ordine superiore.